package design.pattern.Lu19VisitorPattern;

import lombok.Data;

/**
 * @program JavaBase
 * @description: 访问者模式 - 实战：统计报表
 * @author: zhanglu
 * @create: 2020-05-07 23:19:00
 */
public class VisitorPattern04 {

    public static void main(String[] args) {
        CommonEmployee04 commonEmployee04 = new CommonEmployee04();
        commonEmployee04.setName("张三");
        commonEmployee04.setSalary(1000);
        commonEmployee04.setJob("拧螺丝，准备造火箭");
        

        Manager04 manager04 = new Manager04();
        manager04.setName("里斯");
        manager04.setSalary(10000);
        manager04.setPerformance("拿下xxx客户");

        IVisitor04 visitor = new Visitor04();
        commonEmployee04.accept(visitor);
        manager04.accept(visitor);

        int i = visitor.totalSalary();
        System.out.println(i);
    }

}

interface IVisitor04{
    <T> void visit(T t);

    int totalSalary();
}

class Visitor04 implements IVisitor04{

    //部门经理的工资系数是5
    private final static int MANAGER_COEFFICIENT = 5; //员工的工资系数是2
    private final static int COMMONEMPLOYEE_COEFFICIENT = 2; //普通员工的工资总和
    private int commonTotalSalary = 0; //部门经理的工资总和
    private int managerTotalSalary =0;

    @Override
    public <T> void visit(T t) {
        if(t instanceof CommonEmployee04){
            this.commonTotalSalary = this.commonTotalSalary + ((CommonEmployee04) t).getSalary()*COMMONEMPLOYEE_COEFFICIENT;
        }else {
            this.managerTotalSalary = this.managerTotalSalary + ((Manager04) t).getSalary() *MANAGER_COEFFICIENT ;
        }
    }

    @Override
    public int totalSalary() {
        return this.commonTotalSalary + this.managerTotalSalary;
    }
}

@Data
abstract class Employee04{
    private String name;
    private int salary;

    protected abstract void accept(IVisitor04 iVisitor);
}
@Data
class CommonEmployee04 extends Employee04{

    private String job;

    @Override
    protected void accept(IVisitor04 iVisitor) {
        iVisitor.visit(this);
    }
}
@Data
class Manager04 extends Employee04{

    private String performance;

    @Override
    protected void accept(IVisitor04 iVisitor) {
        iVisitor.visit(this);
    }
}


